package iot

import (
	"bytes"
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"time"

	"github.com/axgle/mahonia"
)

type ItemMsg []byte

func NewByteArray(in []byte) ItemMsg {
	return in
}

func (array ItemMsg) ByteArray(start, l int) ItemMsg {
	return array[start : start+l]
}

func (im ItemMsg) ToUInt64() uint64 {
	return binary.LittleEndian.Uint64(im)
}

func (im ItemMsg) ToUInt32() uint32 {
	return binary.LittleEndian.Uint32(im)
}

func (im ItemMsg) ToUInt16() uint16 {
	return binary.LittleEndian.Uint16(im)
}

func (im ItemMsg) ToUInt8() uint8 {
	return im[0]
}

func (im ItemMsg) ToString() string {
	out := []byte{}
	for _, char := range im {
		if char == 0 {
			break
		}
		out = append(out, char)
	}
	return string(out)
}

func (im ItemMsg) ToHexString() string {
	return hex.EncodeToString(im)
}
func (im ItemMsg) ToTime() string {
	if len(im) < 6 {
		return ""
	}
	year := int(im[0]) + 2000
	mouth := int(im[1])
	day := int(im[2])
	hour := int(im[3])
	min := int(im[4])
	sec := int(im[5])
	return fmt.Sprintf("%d-%d-%d %d:%d:%d", year, mouth, day, hour, min, sec)
}

func (im ItemMsg) GbkString(begein, len int) string {
	decoder := mahonia.NewDecoder("GBK")
	msg := im.ByteArray(begein, len).ToString()
	return decoder.ConvertString(msg)
}

func (im ItemMsg) GetString(begein, len int) string {
	return im.ByteArray(begein, len).ToString()
}

func (im ItemMsg) GetUint32(begein int) uint32 {
	return im.ByteArray(begein, 4).ToUInt32()
}

func (im ItemMsg) GetUint16(begein int) uint16 {
	return im.ByteArray(begein, 2).ToUInt16()
}

func (im ItemMsg) GetUint8(begein int) uint8 {
	return im.ByteArray(begein, 1).ToUInt8()
}

func (im ItemMsg) GetNumber(begein, len int) uint32 {
	switch len {
	case 4:
		return uint32(im.ByteArray(begein, 4).ToUInt32())
	case 3:
		return uint32(im.ByteArray(begein, 2).ToUInt16())*256 + uint32(im.ByteArray(begein+2, 1).ToUInt8())
	case 2:
		return uint32(im.ByteArray(begein, 2).ToUInt16())
	case 1:
		return uint32(im.ByteArray(begein, 1).ToUInt8())
	default:
		return 0
	}
}

func FormatJxTime() []byte {
	t := time.Now()
	b := bytes.NewBuffer([]byte{})
	b.WriteByte(byte(t.Year() - 2000))
	b.WriteByte(byte(t.Month()))
	b.WriteByte(byte(t.Day()))
	b.WriteByte(byte(t.Hour()))
	b.WriteByte(byte(t.Minute()))
	b.WriteByte(byte(t.Second()))
	return b.Bytes()
}
